#include <GL/glew.h>

#include "perpixellightingrender.h"
#include "../../data/geometrydata.h"
#include "../../datamanager/geometrydatanode.h"
#include "../../renderer/environment.h"

using namespace PBVP;

PerpixelLightingRender::PerpixelLightingRender()
{

}

PerpixelLightingRender::~PerpixelLightingRender()
{

}

void PerpixelLightingRender::initialize(MainInterface* mainInterface )
{
	RenderPlugin::initialize(mainInterface);
	m_pEnv = &(m_pMainInterface->getEnvironment());
}

RenderPlugin* PerpixelLightingRender::clone()
{
	PerpixelLightingRender *pRender = new PerpixelLightingRender();
	pRender->m_pProgram = this->m_pProgram;
	pRender->m_pMainInterface = m_pMainInterface;
	pRender->m_pEnv = m_pEnv;
	return pRender;
}

bool PerpixelLightingRender::initRender()
{
	if(!glewIsSupported("GL_VERSION_2_0")) return false;
	GLSLProgram *program = new GLSLProgram("shaders/perFraglighting.vert", "shaders/perFraglighting.frag");
	if(!program->isValid()) return false;
	m_pProgram = counted_ptr<GLSLProgram> (program);
	return true;
}

bool PerpixelLightingRender::isSupported(DataInterface *pData) const
{
#ifdef __GNU__
	if(pData->getDataSetType() == GEOMETRY_DATA) return true;
#else
	GeometryData *pGeoData = dynamic_cast<GeometryData *>(pData);
	if(pGeoData) return true;
#endif
	return false;
}

void PerpixelLightingRender::begin()
{
	glUseProgram(m_pProgram->programId());
	m_pProgram->setUniform1i("numLights", int(m_pEnv->numOfLights()));
	glPushAttrib(GL_ALL_ATTRIB_BITS);
}

void PerpixelLightingRender::end()
{
	glPopAttrib();
	glUseProgram(0);
}

void PerpixelLightingRender::render(DataNode *pDataNode)
{
#ifdef __GNU__
	GeometryDataNode *pGeoNode = (GeometryDataNode *)(pDataNode);
#else
	GeometryDataNode *pGeoNode = dynamic_cast<GeometryDataNode *>(pDataNode);
	if(!pGeoNode) return;	// dont draw if not a geometry data
#endif
	GeometryData *pGeoData = (GeometryData *)pGeoNode->data();

	glPushMatrix();

	glEnableClientState(GL_VERTEX_ARRAY);
	glEnableClientState(GL_NORMAL_ARRAY);

	glVertexPointer(3, GL_FLOAT, 0, pGeoData->vertexPointer());
	glNormalPointer(GL_FLOAT, 0, pGeoData->normalPointer());
	glDrawElements(GL_TRIANGLES, 3*pGeoData->numOfTriangles(),
		GL_UNSIGNED_INT, pGeoData->triangleIndexPointer());

	glPopMatrix();
}

Q_EXPORT_PLUGIN2(perpixellighting, PerpixelLightingRender)
